package gek.uni.aspirant.uml.utils;

import java.util.ArrayList;
import java.util.Collection;

import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.common.util.WrappedException;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.uml2.uml.Class;
import org.eclipse.uml2.uml.Model;
import org.eclipse.uml2.uml.Package;
import org.eclipse.uml2.uml.PackageableElement;
import org.eclipse.uml2.uml.UMLPackage;
import org.eclipse.uml2.uml.resource.UMLResource;

public class UmlUtils {

  /**
   * Загружает UML-ресурс из файла *.uml
   * 
   * @param uri
   * @return
   */
  public static Resource loadResource(URI uri) {

    Resource resource = null;

    try {
      ResourceSet resourceSet = new ResourceSetImpl();

      resourceSet.getPackageRegistry().put(UMLPackage.eNS_URI,
          UMLPackage.eINSTANCE);

      resourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(
          UMLResource.FILE_EXTENSION, UMLResource.Factory.INSTANCE);

      resource = resourceSet.getResource(uri, true);

    } catch (WrappedException we) {
      we.printStackTrace();
    }

    return resource;
  }

  /**
   * Возвращает коллекцию, содержащую все классы из пакета pack
   * 
   * @param pack
   * @return
   */
  public static Collection<Class> findClassesInPackage(Package pack) {
    Collection<Class> result = new ArrayList<Class>();
    for (PackageableElement element : pack.getPackagedElements()) {
      if (element instanceof Package)
        result.addAll(findClassesInPackage((Package) element));
      else if (element instanceof Class)
        result.add((Class) element);
    }
    return result;
  }

  /**
   * Возвращает все классы, которые есть в модели model
   * 
   * @param model
   * @return
   */
  public static Collection<Class> findClassesInModel(Model model) {
    Collection<Class> result = new ArrayList<Class>();

    EList<PackageableElement> packagedElements = model.getPackagedElements();
    for (PackageableElement pack : packagedElements) {
      if (pack instanceof Package)
        result.addAll(findClassesInPackage((Package) pack));
    }
    return result;
  }
  
  
  
  @Deprecated
  public static void main(String[] args) {
    URI uri = URI.createFileURI("/home/arkady/uml.uml");
    Resource resource = loadResource(uri);
    System.out.println(resource);
    Model model = (Model) EcoreUtil.getObjectByType(resource.getContents(),
        UMLPackage.Literals.MODEL);
    Collection<Class> classes = findClassesInModel(model);
    for (Class clazz : classes) {
      System.out.println(clazz.getPackage().getName() + "." + clazz.getName());
    }
  }
}
